//------------------------------------------------------------------------------
//SFWK Framework
//Copyright (C) 2011 SQLI

//This program is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.

//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.

//You should have received a copy of the GNU General Public License
//along with this program.  If not, see <http://www.gnu.org/licenses/>.
//------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace SFWK.Core.Error
{
    public static class ErrorHelper
    {

        /// <summary>
        /// Transforms error to user friendly message
        /// </summary>
        /// <param name="error">Error</param>
        /// <returns>User message</returns>
        public static string ResolveError(FaultException error)
        {
            try
            {
                SFWK.Core.SFWKError specificError = null;
                System.ServiceModel.Channels.MessageFault mf = error.CreateMessageFault();
                if (mf.HasDetail)
                {
                    using (var reader = mf.GetReaderAtDetailContents())
                    {
                        //Gets the type of the specific fault detail
                        Type type = System.Reflection.Assembly.Load("SFWK.Core").GetTypes().First(t => (t.BaseType == typeof(SFWK.Core.SFWKError)) && (t.Name.ToString() == reader.Name));

                        //Deserialize de fault detail to get the object
                        if (type != null)
                            specificError = (SFWK.Core.SFWKError)new System.Runtime.Serialization.DataContractSerializer(type).ReadObject(reader);
                    }
                }
                if (specificError != null)//Right custom exception type found, translate it to user friendly error message
                {
                    //Checks if labels are to be translated in the exception's parameter list, and translate them
                    if (specificError.Parameters != null)
                    {
                        for (int i = 0; i < specificError.Parameters.Count; i++)
                        {
                            if (specificError.Parameters[i].Contains("ErrorMessage."))
                            {
                                specificError.Parameters[i] = specificError.Parameters[i];
                            }
                        }
                    }

                    //If error translation contains more {x} than submited parameters, they are deleted
                    string translation = specificError.ErrorCode;
                    int count = 0;

                    if (specificError.Parameters != null)
                    {
                        count = specificError.Parameters.Count;
                    }
                    while (translation.Contains("{" + count.ToString() + "}"))
                    {
                        translation = translation.Replace("{" + count.ToString() + "}", "");
                        count++;
                    }
                    if (specificError.Parameters != null)
                    {
                        return string.Format(translation, specificError.Parameters.ToArray());
                    }
                    return translation.Replace("\"","");
                }
                else
                {
                    //custom exception type not found, translate UnexpectedError to user friendly error message
                    return new UnexpectedError(null).ErrorCode;
                }
            }
            catch (Exception ex)
            {
                string strError = ex.Message;
                return "ResolveError";
            }
        }

    }
}

